#include "UserInfo.h"
#include "CryptoUtil.h"
#include <workflow/MySQLResult.h>
#include <nlohmann/json.hpp>
#include <map>
#include <string>
#include <iostream>
#include <functional>
using std::map;
using std::string;
using namespace protocol;
using namespace wfrest;
using JSON = nlohmann::json;

UserInfo::UserInfo(wfrest::HttpServer & server)
:m_server(server)
{
}

struct UserInfoContext{
    HttpResp* resp;
    string username;
    string signupat;
};

void UserInfomysqlCallback(WFMySQLTask * mysqlTask){
    UserInfoContext * context = static_cast<UserInfoContext*>(series_of(mysqlTask)->get_context());
    if(mysqlTask->get_state() !=WFT_STATE_SUCCESS){
        context->resp->String("mysqlTask failed");
        return;
    }

    MySQLResultCursor cursor(mysqlTask->get_resp());

    if(cursor.get_cursor_status()==MYSQL_PACKET_ERROR){
        context->resp->String("error");
        return ;
    }

    if(cursor.get_cursor_status()==MYSQL_STATUS_GET_RESULT){
        map<string,MySQLCell> row;
        cursor.fetch_row(row);
        if(row.size()==0){
            context->resp->String("error");
            return;
        }
        JSON js;
        js["data"] = {{"Username",context->username},
                      {"SignupAt",row["created_at"].as_string()}};
        context->resp->String(js.dump());
    }
}


void UserInfo::userinfo_module(){
    m_server.GET("/user/info", [](const HttpReq *req, HttpResp *resp,SeriesWork * series){
        string username;
        string token;
        username = req->query("username");
        token = req->query("token");
        if(CryptoUtil::verify_token(token,username)){
            string sql = "select * from tbl_users where username = '"+username+"';";
            WFMySQLTask * mysqltask = WFTaskFactory::create_mysql_task("mysql://root:123@localhost/newCloudDisk",3,UserInfomysqlCallback);
            mysqltask->get_req()->set_query(sql);
            UserInfoContext * ctx = new UserInfoContext{resp,username,{}};

            series->set_context(ctx);
            series->set_callback([ctx](const SeriesWork *){
                delete ctx;
            });
            series->push_back(mysqltask);
        }else{
            resp->String("error");
        }
    });
}
void UserInfo::start(){
    userinfo_module();
}